<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>模板语法</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
</head>

<body>
<div id="app">
    <fieldset>
        <legend>v-text</legend>
        <p>{{msg}}</p>
        <p v-text='msgtxt'></p>
        <p>注：双花括号方式 {{}} 等于v-text</p>
    </fieldset>
    <fieldset>
        <legend>v-html区别</legend>
        <p v-html="msg1"></p>
        <p>{{msg1}}</p>
        <span>通过插值语法输出的是纯文本，浏览器不会对其再进行html解析，但v-html会将其中的html标签再解析后输出</span>
    </fieldset>
    <fieldset>
        <legend>v-bind属性绑定</legend>
        <img :src="mysrc" :title='mytitle'>
        <span>v-bind,主要用于html属性绑定，比如CSS样式标签title抑或img的src等</span>
    </fieldset>
    <fieldset>
        <legend>v-on绑定事件</legend>
        <button type="button" @click='click'>mybutton</button>
        <span>语法1：v-on:click="say"</span>
        </br>
        <button type="button" @click="myclick('mybutton', $event)">mybutton</button>
        <span>语法2：v-on:click="say('参数', $event)"</span>
        </br>
        <div @click='divclick' :style="styleobj">
            <button type="button" @click="btnclick">mybtclick</button>
            <button type="button" @click.stop="btnclick">btnclick</button>
            <!-- 不使用stop修饰符点击button会弹出2次对话框，使用后只弹出一次，阻止了事件冒泡 -->
        </div>
        作用：绑定事件</br>
        语法：v-on:click="say" or v-on:click="say('参数', $event)" </br>
        简写：@click="say" </br>
        说明：绑定的事件定义在methods
        </span>
    </fieldset>
    <fieldset>
        <legend>v-model</legend>
        <input type="text" v-model="msg3" placeholder="edit me">
        <p>Message is: {{ msg3 }}</p>
        <span>作用：在表单元素上创建双向数据绑定,监听用户的输入事件以更新数据</span>
    </fieldset>
    <fieldset>
        <legend>条件渲染</legend>
        <fieldset>
            <legend>v-if条件渲染单个元素</legend>
            <h3 v-if='OK'>v-if为true时显示h3标签</h3>
        </fieldset>
        <fieldset>
            <legend>v-if条件渲染分组(一组嵌套的元素)</legend>
            <div v-if="OK1">
                <ul>
                    <li>1</li>
                    <li>2</li>
                    <li>3</li>
                </ul>
                <h4>v-if为true时显示div内所有元素</h4>
            </div>
        </fieldset>
        <fieldset>
            <legend>v-else和v-else-if</legend>
            <div v-if="type === 'A'">
                A
            </div>
            <div v-else-if="type === 'B'">
                B
            </div>
            <div v-else-if="type === 'C'">
                C
            </div>
            <div v-else>
                Not A/B/C
            </div>
            <p>type值为A,B,C任意一个时，显示当前值的元素，非ABC任意值时显示Not A/B/C；通过app.type=""查看效果</p>
        </fieldset>
        <fieldset>
            <legend>v-if弊端</legend>
            <div v-if="toggle_display">
                <input type="text" placeholder="账号" key="name">
            </div>
            <div v-else="toggle_display">
                <input type="text" placeholder="密码" key="psd">
            </div>
            <div>
                <button @click="toggle_click">切换</button>
            </div>
            <p>Vue在渲染元素时，出于效率考虑，会尽可能地复用已有的元素而非重新渲染，会出现只渲染变化的元素</p>
            <p>点切换按钮两个输入框会切换，如果任意一个输入框输入内容后再点切换会发现输入的内容并没有清除，说明input元素被复用了</p>
            <p>解决方法：加key，唯一，提供key值可以来决定是否复用该元素</p>
        </fieldset>
        <fieldset>
            <legend>v-show</legend>
            <h3 v-show='OK2'>v-show</h3>
            <p>v-if：不显示时直接移除DOM元素</p>
            <p>v-show：只改变css的display属性，即添加v­show的元素永远存在也页面中，只是根据显示与否改变display</p>
        </fieldset>
        <fieldset>
            <legend>v-for列表渲染</legend>
            <span>v-for="item in items"语法</span>
            <ul>
                <li v-for='item in lists'>{{item}}</li>
            </ul>
            <span>v-for=(item, index) in lists"语法;渲染结果为iteam.value加index</span>
            <ul>
                <li v-for='(item1,index) in lists1'>{{item1.value}}+{{index}}</li>
            </ul>
            <span>通过v-for遍历对象属性，li绑定的值是一个对象，对象下的属性都会显示</span>
            <ul>
                <li v-for='objvalue in Object'>{{objvalue}}</li>
                <!-- 注意此处直接绑定数据是一个对象的值objvalue -->
            </ul>
            <span>v-for='(value,key,index) in lists'</span>
            <ul>
                <li v-for='(value,key,index) in lists2'>序号{{index}}：{{key}}：{{value}}</li>
            </ul>
            <p>v-for要写在需要遍历的元素上</p>
            <p>遍历一个对象的多个属性</p>
        </fieldset>
    </fieldset>
    <fieldset>
        <legend>性能相关</legend>
        <fieldset>
            <legend>v-pre</legend>
            <span v-pre>{{vpre}}</span>
            <span>vpre真实在data内的值是test，使用v-pre指令后vue跳过渲染此标签console.log(app.vpre)查看实际值</span>
        </fieldset>
        <fieldset>
            <legend>v-once</legend>
            <div>
                <p>可以改变：{{ voncemsg }}</p>
                <p v-once>不可以改变：{{ voncemsg }}</p>
                <p>注：通过app.voncemsg = '要改的值'查看使用v-once和不使用的区别</p>
            </div>
        </fieldset>
    </fieldset>

</div>
<script>
    let app = new Vue({
        el: '#app',
        // Vue 实例的数据对象，用于给 View 提供数据
        data: {
            msg: 'Hello Vue',
            msgtxt: '我是通过v-text渲染的',
            msg1: '<b style="color:red">v-html</b>',
            msg2: [1, 2],
            mysrc: 'http://www.runoob.com/try/demo_source/smiley-2.gif',
            mytitle: 'v-bind属性绑定',
            styleobj: {
                width: '100%',
                height: '25px',
                border: '1px solid red'
            },
            msg3: '',
            OK: true,
            OK1: true,
            type: '1',
            toggle_display:true,
            OK2: true,
            lists: [1, 2, 3],
            lists1: [
                {value: 'name1'},
                {value: 'name2'},
                {value: 'name3'}
            ],
            Object: {
                name: '小张',
                age: '18',
                sex: '男'
            },
            lists2: {
                name: '小三',
                age: '50',
                sex: '男'
            },
            vpre: 'test',
            voncemsg: '我没有使用v-once',
        },
        methods: {
            click: function (e) {
                alert(e.target.tagName)
            },
            myclick: function (message, $event) {
                alert(message);
                alert($event.target.tagName)
            },
            divclick: function (e) {
                alert(e.target.tagName)
            },
            btnclick: function (e) {
                alert(e.target.tagName)
            },
            toggle_click:function () {
                this.toggle_display = !this.toggle_display
            }
        }
    });
    //访问实例属性
    console.log(app.$el);
    console.log(app.$data);
    //访问data属性
    console.log(app.msg);
    /*
        * el
        *
        *
        * 一、el:
        * 类型：string，可以是DOM、标签、css语法
        * 提供一个在页面上已存在的 DOM 元素作为 Vue 实例的挂载目标
        *
        * 二、data
        * 类型：Object
        * 定义数据，例如：  data:{n:1,m:2}
        *
        * 三、访问实例属性
        * app1.$el
        * app1.$data
        * >>>访问data属性
        * app1.msg
        *
        * 四、插值语法，也就是 {{}} 语法
        * 解释：{{}}从数据对象data中获取数据,数据对象的属性值发生了改变，插值处的内容都会更新
        * 说明：可以进行简单运算，可以使用三元运算，但不能写表达式{{  if(6>3){}  }}如这样写会报错
        *
        * v-html
        * 用于解析并输出html，它与{{}}}区别在于通过插值语法输出的是纯文本，浏览器不会对其再进行html解析
        * 但v-html会将其当html标签解析后输出(例：第2和第3个p标签内容)
        *
        * v-bind
        * 简写 :src="msg"
        * 主要用于html属性绑定，比如CSS样式标签title抑或img的src等
        *
        * v-on
        * 作用：绑定事件
        * 语法：v-on:click="say" 和 v-on:click="say('参数', $event)"
        * 简写：@click="say"
        * 说明：绑定的事件定义在methods
        * 事件修饰符
        * >>> .stop 阻止冒泡，调用 event.stopPropagation()
        * >>> .prevent 阻止默认行为，调用 event.preventDefault()
        * >>> .capture 添加事件侦听器时使用事件捕获模式
        * >>> .self 只当事件在该元素本身（比如不是子元素）触发时，才会触发事件
        * >>> .once 事件只触发一次
        *
        * v-model
        * 作用：在表单元素上创建双向数据绑定
        * 说明：监听用户的输入事件以更新数据
        *
        * v-if
        * 说明：根据表达式的值的真假条件，销毁或重建元素
        * v-else 元素必须紧跟在带 v-if 或者 v-else-if 的元素的后面，否则它将不会被识别
        * v-else-if 也必须紧跟在带 v-if 或者 v-else-if 的元素之后
        * 因为v-if是一个指令，所以必须将它添加到一个元素上。如果想切换多个元素时可以把一个 <template> 元素当做不可见的包裹元素
        * 并在上面使用 v-if,最终的渲染结果将不包含 <template> 元素;也可以使用其他可见元素进行包裹如div
        *
        * v-show
        * 说明：v-show不支持 <template> 元素，也不支持 v-else
        * 带有 v-show 的元素始终会被渲染并保留在 DOM 中。v-show 只是简单地切换元素的 CSS 属性 display
        *
        * >>> v-if和v-show区别
        * >>> v-if是根据条件真假来确定是否渲染元素，如果条件不成立则不渲染元素
        * >>> v-show会将元素全部渲染出来，然后根据条件真假去改变元素的display属性确定是否显示元素
        * >>> v-if是决定是否创建DOM，而v-show则是DOM始终存在，只是改变了显示样式
        *
        * v-for
        * 说明：基于源数据多次渲染元素或模板块，即将一个数组渲染为列表项
        * v-for指令需要限定格式为 item in items 的特殊语法，也提供了key和index两个参数,语法为v-for='(item,key,index) in items'
        *
        * v-pre
        * 说明：vue会跳过这个元素和它的子元素的编译过程。可以用来显示原始 Mustache 标签。跳过大量没有指令的节点会加快编译。
        *
        * v-cloak
        * 解决初始化慢导致页面闪动,一般和display结合使用
        * 根元素div加v-cloak
        * [v-cloak]{
        *           display: none;
        *       }
        *
    */

</script>
</body>

</html>